****************************************************************************************************
*                                 Dokumentace programu Zebra                                       *
****************************************************************************************************


Autor
*****
eslav Przywara aka Chester


Soubory
*******
zebra.pl - zdrojovy kod programu.
dokumentace.txt - soubor s dokumentaci k programu.
priklad.txt - vzorovy znalostni soubor (databaze znalosti).
zadani.txt - priklad 2 zadani ulohy zebra.
geologove.txt - zadani ve forme databaze znalosti, pripravene k pouziti (testovaci soubor).
nadnarodni_ulice.txt - dtto.


Popis
*****
Program Zebra resi logicke hadanky, oznacovane jako zebry (priklad viz zadani.txt). Zebra je druh hlavolamu, v jeho zadani se lustitel dozvi, e ma k dispozici urcite informace o urcitych osobach, mistech, vecech apod. (dale jako entity) v ruznych kategoriich - zaliby, jmeno apod. (dale jako vlastnosti), ale ma k dispozici jen tolik souvislosti, aby bylo obtine se dobrat ke zbytku a pritom aby reseni bylo jedine.
Program vyuziva prirozenych vlastnosti Prologu, pro reseni logickych zadani. Umi resit vztahy typu "nejaka (nejake) vlastnost(i) patri k jedne entite" a "nejaka vlastnost patri k entite sousedici s entitou, ktere patri nejaka jina vlastnost". Co neumi, jsou vztahy typu "nejaka vlastnost nepatri k entite, ke ktere patri nejaka jina vlastnost" - toto je videt u druheho prikladu (viz zadani.txt), ktery program neumi vyresit jednoznacne.


Provedeni
*********

1. Spusteni programu
Program se spusti automaticky a zepta se na soubor s databazi znalosti. Cesta k souboru musi byt zadana v apostrofech a cele zadani musi byt ukoncene teckou.

2. Nacteni zadani
Zadani je nakonzultovano (nacteno) pomoci souboru, ktery zada uzivatel. Soubor musi byt ve tvaru danem specifikaci (viz bod Specifikace znalostniho souboru nize). K definici vzajemnych zavislosti mezi entitami slouzi 3 predikaty: patriksobe/2, sousede/2 a vedlesebe/2.

3. Hledani vsech reseni
Program na zacatku zinicializuje seznam, ktery svou strukturou odpovida ocekavanemu tvaru reseni, tj. obsahuje tolik prvku, kolik je v zadani ulohy ruznych entit. Kazda entita je reprezentovana 2-prvkovym seznamem: prvni prvek odpovida pozici entity v hlavnim seznamu (definuje poradi), druhy prvek je seznamem vlastnosti daneho prvku. Vsechny vlastnosti jsou inicializovany jako anonymni.
Pote pomoci predikatu findall "posbirame" vsechny reseni. Predikat findall pouzivame proto, ze v pripade, ze nenalezne zadne reseni, "vraci" prazdny seznam (narozdil od bagof nebo setof). Jeho nevyhodou ovsem je, ze nesesbira jenom jedinecna reseni - proto na konci jeste musime vysledny seznam reseni zbavit duplicit.
Jednotlive reseni ziskame tak, ze se snazime postupne zunifikovat anonymne zinicializovany seznam promennych tak, aby splnoval vsechny zadane predikaty. Zde vyuzivame predikat setof, kterym postupne sesbirame vsechny klauzule definujici vzajemne zavislosti - to celkem provedeme 3-krat (pro kazdy predikat jednou).
Program automaticky vypise vsechna reseni na vystup.

4. Dalsi moznosti
Uzitecny zejmena pro "ladeni zadani" zebry je predikat znovanacti/0. Ten znova nacte soubor s definicemi znalosti a spocita nova reseni, ta okamzite vypise.


Specifikace znalostniho souboru
*******************************
Priklad vzoroveho znalostniho souboru: priklad.txt.

V znalostnim souboru MUSI byt uvedeny nasledujici 2 predikaty:

pocet_prvku(N).
Kde N odpovida poctu domku (entit).

pocet_vlastnosti(M).
Kde M odpovida poctu vlastnosti jednotlive entity (poradi se mezi ne nepocita!).

Dale by mely byt uvedeny nasledujici 3 predikaty (ne nutne vsechny, ale v pripade, ze predikat neobsahuje zadnou klauzuli, MUSI by obsahovat defaultni! - viz priklad.txt)

patriksobe/2
patriksobe(Poradi,[Vlastnost1, ..., VlastnostM]).
Predikat definuje entitu pomoci vyctu jejich (ne)znamych vlastnosti.
Je nutne uvest vsechny vlastnosti, i ty ktere nejsou zname - nahradime je znakem '_'. Poradi odpovidajicich si vlastnosti musi byt ve vsech predikatech stejne!

sousede/2
sousede(patriksobe(...),patriksobe(...)).
Predikat definuje vlastnosti nejakych prvku, ktere jsou v sousedkem vztahu vlevo/vpravo (vime, ktery je na ktere strane), 1 argument odpovida pozici vlevo, druhy vpravo. Vyuziva predikat patriksobe/2.

vedlesebe/2
vedlesebe(patriksobe(...),patriksobe(...)).
Predikat definuje vlastnosti nejakych prvku, ktere jsou v sousedkem vztahu vedle-sebe (nevime, ktery je na ktere strane), vyuziva predikat patriksobe/2.


Odladeno
********
Program byl odladen v SWI-Prologu.
